#include "hash_table.h"
#include "client.h"
#include <string.h>
#include "serveur.h"

static int cle=1;

void printTable(struct hash_table* H){
  int i,j;
  fprintf(stderr,"nbre Fichier : %d\n", H->nbreFichier-1);
  fprintf(stderr,"nbreClient : %d\n",H->nbreClient);
  int f = H->nbreFichier-1;
  int c = H->nbreClient;
  struct fichier ** F=H->tab;
  fprintf(stderr,"les fichiers : ");
  for(i=0;i<f;i++){
    fprintf(stderr,"\n-%s, taille %d, taille des pieces %d, cle %s",F[i]->nom, F[i]->taillefichier, F[i]->taillepiece, F[i]->clef);
  }
  if(!f)
    fprintf(stderr,"aucun");
  fprintf(stderr,"\n\n");

  for(i=0;i<c;i++){
    for(j=0;j<f;j++){
      if(H->possesseur[i][j+1]){
	fprintf(stderr,"le client %d possede le fichier %d avec telle valeur :\n",i+1,j+1);
	printFichierCle(j, H->tab, f);
      }
    }
  }
}


struct hash_table* init_table(void)
{
  struct hash_table * ret = malloc(sizeof(struct hash_table));
  ret->possesseur = malloc(sizeof(int*));
  ret->possesseur [0] = malloc(sizeof(int));
  ret->possesseur [0][0] = malloc(sizeof(int ));
  ret->nbreFichier = 1;
  ret-> nbreClient = 0;
  ret->tc=malloc (sizeof(struct table_client*));
  ret->tc->tabClient[0]=malloc (sizeof(struct client*));
  return ret;
}




void ajouter_fichier(struct hash_table * T, struct fichier * F, struct client * C)
{
  int i = 0;
  int j = 0;
  printf("fichier:%d\n",(T->nbreFichier)-1);

  while (i<T->nbreFichier-1 && strcmp(T->tab[i]->clef, F->clef)!=0)
    {
      i++;
    }
  
  if (i == T->nbreFichier-1 || T->nbreFichier == 0)
    {
      if(i == MAX)
	{
	  fprintf(stderr, "trop de clients connectes\n");
	}
      else
	{
	  /*if(!i && T->nbreFichier!=0)
	    i++;*/

	  T->nbreFichier++;
	  T->tab[i] = malloc(sizeof(struct fichier*)); 
	  T->tab[i] =  F;
	  
	  
	  for(int k = 0 ; k<T->nbreClient ; k++)
	    {
	      T->possesseur[k][T->nbreFichier]=malloc(sizeof(int));
	      T->possesseur[k][T->nbreFichier]=0;

	    }
	  j = ajouter_client(T,C);

	  T->possesseur[j][T->nbreFichier-1] = 1;
	}
    }
  else
    {
      int l = ajouter_client(T,C);
      T->possesseur[l][i+1] = 1;
    }

}





int ajouter_client(struct hash_table * T, struct client * C)
{
  int i = 0;
  while(i != T->nbreClient && T->tc->tabClient[i]->clef != C->clef)
    {
      i++;
    }

  if (/*(T->possesseur[i][0] != C->clef) && */(i == T->nbreClient || T->nbreClient == 0) )
    {
     
      fprintf(stderr,"plok\n");
      T->nbreClient++;    
      T->tc->tabClient[T->nbreClient-1]= malloc (sizeof(struct client *));
      T->tc->tabClient[T->nbreClient-1]= C;

      
      T->possesseur[T->nbreClient-1] = realloc(T->possesseur[T->nbreClient-1], sizeof(int)*T->nbreFichier);
      T->possesseur[T->nbreClient-1][0] = C->clef;
      for(int j =0 ; j<T->nbreFichier ; j++)
	{
	  T->possesseur[T->nbreClient-1][j+1]=0;
	}
      return T->nbreClient;
    }
  else
    return i;
}

struct client * creerClient(char * ip, int port){

  struct client * C = malloc(sizeof(struct client));
  C->IP=malloc(sizeof(char)*strlen(ip));
  strcpy(C->IP,ip);
  C->port=port;
  C->clef = cle++;

  return C;
}


void supprimer_client(struct srv *s){

  int i=0;
  int j,k,r,ind;
  while (s->c->clef != s->t->possesseur[i][0])
    i++;
 
  for (j=i;j<s->t->nbreClient-1;j++){
    for (k=0;k<s->t->nbreFichier+1;k++){
      s->t->possesseur[j][k]=s->t->possesseur[j+1][k];
    }
  }
  
  /* for (k=0;k<s->t->nbreFichier+1;k++)
     free(s->t->possesseur[s->t->nbreClient-1][k]);*/
 
  for (j=1;j<s->t->nbreFichier+1;j++){
    r=0;
    for (k=0;k<s->t->nbreClient-1;k++){
      if (s->t->possesseur[k][j]==0 && k!=i)
	r++;
    }
    if (r==s->t->nbreClient-1){
      for (ind=j-1;ind<s->t->nbreFichier-1;ind++)
	s->t->tab[ind]=s->t->tab[ind+1];
      //  free(s->t->tab[s->t->nbreFichier-2]);
      
      for(k=j;k<s->t->nbreFichier+1;k++){
	for (r=0;r<s->t->nbreClient-1;r++){
	  s->t->possesseur[r][k]=s->t->possesseur[r][k+1];
	}
      }
      /* for (k=0;k<s->t->nbreClient;k++)
	 free(s->t->possesseur[k][s->t->nbreFichier]);*/
      s->t->nbreFichier--;
      j--;
    }
  }
  i=0;
  while (s->c->clef != s->t->tc->tabClient[i]->clef)
    i++;
  for (j=i;j<s->t->nbreClient;j++)
    s->t->tc->tabClient[j]=s->t->tc->tabClient[j+1];
  
  // free(s->t->tc->tabClient[s->t->nbreClient-1]);
  s->t->nbreClient--;
  
 
}

int estClient(char * IP, struct hash_table* H){
  int nbC = H->nbreClient, i;

  for(i=0;i<nbC;i++){
    if(strcmp(H->tc->tabClient[i]->IP, IP)==0)
      return i;
  }

  return -1;
}

